/****************************************************
 ****************************************************
 ***                                              ***
 ***   Project:  YAVRS                            ***
 ***   (Yet Another Virtual Reality System)       ***
 ***   ________________________________________   ***
 ***                                              ***
 ***   File:     yavrsWavefrontObj.h              ***
 ***   Authors:  Steve Conner & Thomas Marrinan   ***
 ***   Date:     11/05/2011                       ***
 ***                                              ***
 ****************************************************
 ****************************************************/

#ifndef YAVRS_WAVEFRONT_OBJ_H
#define YAVRS_WAVEFRONT_OBJ_H

#include <cstring>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>

#ifdef __APPLE__
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#include <GLUT/glut.h>
#endif
#ifndef __APPLE__
#include <AL/alut.h>
#include <GL/glut.h>
#endif

using namespace std;


/***************************************************
 ***                                             ***
 ***     Loads Wavefront (.obj) files            ***
 ***     for OpenGL rendering                    ***
 ***                                             ***
 ***     In Blender:                             ***
 ***       1) File->Export->Wavefront (.obj)     ***
 ***       2) Export Wavefront OBJ               ***
 ***       3) Select:                            ***
 ***            - Selection Only                 ***
 ***            - Rotate X90                     ***
 ***            - Edges                          ***
 ***            - Triangulate                    ***
 ***            - Materials                      ***
 ***            - Keep Vert Order                ***
 ***       4) Unselect Everything Else           ***
 ***       5) Export                             ***
 ***                                             ***
 ***************************************************/


class object {
public:
	vector<int**> faceList;			// list of faces (indices of vertices and normals)
	int shadeMode;					// smooth or flat shading
	char matName[60];				// name of material

	object() {};
	~object() { faceList.clear(); }
};

class material {
public:	
	char matName[60];				// name of material
	float Ns[1];					// shininess exponent
	float Ka[4];					// ambient color
	float Kd[4];					// diffuse color
	float Ks[4];					// specular color
	int illum;						// tag for use of specular highlight

	material() {};
	~material() {};
};


//! Brief description
class yavrsWavefrontObj {
private:
	/*** Members ***/
	vector<double*> vertList;		// list of vertices
	vector<double*> normList;		// list of normals
	vector<object*> objList;		// list of objects
	vector<material*> matList;		// list of materials
	double bounds[6];				// bounds (xMin, xMax, yMin, yMax, zMin, zMax)
    float position[3];              // position
	float rotation[4];              // rotation
	float scale[3];                 // scale

	//! Calculate Object Normals
	void calculateNormals();
	
	//! Calculate Bounds of the Object
	void calculateBounds();

	ALuint source;
	ALuint buffer;

	
public:
	/*! Constructor/Destructor */
	yavrsWavefrontObj();
	~yavrsWavefrontObj();

	//! Get Bounds of Object (xMin, xMax, yMin, yMax, zMin, zMax)
	double* getBounds();
    
    //! Normalizes Vertices of Object - Center = (0, 0, 0), and Max Length = 1.0
    void normalizeObject();
	
	//! Load OBJ File (and corresponding MTL)
	void load(const char* fileName);
	
	//! Draw OBJ
	void draw();

	void setPosition(float x, float y, float z);
	void setRotation(float angle, float x, float y, float z);
	void setScale(float x, float y, float z);

	double rayCollision(double *p1, double *p2);
	
	void loadWaveFile(const char * filename);
	void playWaveFile();
};
#endif // YAVRS_WAVEFRONT_OBJ_H


